package com.escom.healthlc.security;


import java.util.Iterator;
import java.util.Map;

import javax.faces.FacesException;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;

public class ExceptionHandlerListener extends ExceptionHandlerWrapper {

    private final static Logger logger = LoggerFactory.getLogger(ExceptionHandlerListener.class);
    private ExceptionHandler wrapped;

    public ExceptionHandlerListener(ExceptionHandler wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public ExceptionHandler getWrapped() {
        return this.wrapped;
    }

    @Override
    public void handle() throws FacesException {
        for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
            ExceptionQueuedEvent event = i.next();
            ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
            final FacesContext facesContext = FacesContext.getCurrentInstance();
            final Map<String, Object> requestMap = facesContext.getExternalContext().getRequestMap();
            final NavigationHandler navigationHandler = facesContext.getApplication().getNavigationHandler();
            try {
                Throwable t = context.getException();
                if (t instanceof ViewExpiredException) {
                    ViewExpiredException vee = (ViewExpiredException) t;                    
                    logger.error("La sesión del usuario ha expirado: {}", t.getMessage());
                    // Push some useful stuff to the request scope for use in the page
                    requestMap.put("currentViewId", vee.getViewId());
                    navigationHandler.handleNavigation(facesContext, null, "/login");
                    facesContext.renderResponse();
                } 
//                else if (t instanceof ManagedBeanCreationException) {                    
//                    logger.error("Error al crear bean: {}", t.getMessage());                    
//                    navigationHandler.handleNavigation(facesContext, null, "error?faces-redirect=true codError=msg_error_mbc");
//                    facesContext.renderResponse();
//                }
                else if (t instanceof DataAccessException) {
                    logger.error("Error al accesar a la base de datos: {}", t.getMessage());
                    requestMap.put("error.dae","DataAccessException");
                    navigationHandler.handleNavigation(facesContext, null, "error?faces-redirect=true codError=msg_error_bd");
                }
                else {
                    logger.error("Ocurrio un error en el sistema: {}", t.getMessage());
                    requestMap.put("error.sistema","Error del sistema");
                    navigationHandler.handleNavigation(facesContext, null, "error?faces-redirect=true codError=msg_error_sistema");
                }
            } finally {
                i.remove();
            }
        }

        // At this point, the queue will not contain any ViewExpiredEvents. Therefore, let the parent handle them.
        getWrapped().handle();
    }
}
